﻿using System;
using System.Collections.Generic;
using CoTime.DataAccess;
using CoTime.Model;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;

namespace CoTimeTest
{
    /// <summary>
    ///This is a test class for Repository<Task>Test and is intended
    ///to contain all Repository<Task>Test Unit Tests
    ///</summary>
    [TestClass()]
    public class RepositoryTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        private static readonly String filePath = @"today.xml";

        /// <summary>
        ///A test for AddItem
        ///</summary>
        [TestMethod()]
        public void AddItemTest()
        {
            Repository<Task> target = new Repository<Task>(filePath);
            
            Task task = BuildATask(1, "Task Repository 测试");
            target.ItemAdded += new EventHandler<ItemAddedEventArgs<Task>>(target_ItemAdded);
            Int32 expected = target.GetItems().Count + 1;
            target.AddItem(task);
            Int32 actual = target.GetItems().Count;
            Assert.AreEqual(expected, actual);
        }

        void target_ItemAdded(object sender, ItemAddedEventArgs<Task> e)
        {
            Debug.WriteLine(sender.ToString());
            Debug.WriteLine(e.NewItem.ToString());
        }

        /// <summary>
        ///A test for GetItems
        ///</summary>
        [TestMethod()]
        public void GetItemsTest()
        {
            Repository<Task> target = new Repository<Task>(filePath);
            List<Task> expected = new List<Task>(){ BuildATask(1, "Task Repository 测试")};
            target.AddItem(BuildATask(1, "Task Repository 测试"));
            List<Task> actual;
            actual = target.GetItems();
            //unsaved
            Assert.AreEqual(expected.Count, actual.Count);
            if (expected!=null && expected.Count > 0 && expected.Count == actual.Count)
            {
                Assert.AreEqual(expected[0].Title, actual[0].Title);
            }
            //saved
            target.Save();
            target = new Repository<Task>(filePath);//reinit Repository<Task>
            actual = target.GetItems();
            Assert.AreEqual(expected.Count, actual.Count);
            if (expected != null && expected.Count > 0 && expected.Count == actual.Count)
            {
                Assert.AreEqual(expected[0].Title, actual[0].Title);
            }
        }

        [TestMethod()]
        public void ScoreTest()
        {
            Task task = BuildATask(2,"score test");
            Score expected = new Score()
            {
                EstiPomos = 1,
                UsedPomos = 1
            };
            Score actual = task.Score;
            Assert.AreEqual(expected.EstiPomos,actual.EstiPomos);
            Assert.AreEqual(expected.UsedPomos, actual.UsedPomos);
        }
        
        /// <summary>
        ///A test for Save
        ///</summary>
        [TestMethod()]
        public void SaveTest()
        {
            Repository<Task> target = new Repository<Task>(filePath);
            Task task = BuildATask(1, "Task Repository 测试");
            target.AddItem(task);
            target.Save();
        }

        #region 【 Helpers 】

        private static Task BuildATask(Int32 id, String title)
        {
            Task task = new Task()
            {
                Id = id,
                Title = title,
                Done = false,
                Acts = new List<Act>() { 
                        new Act(){
                            ActType = ActType.AddEstiPomo,
                            Time = DateTime.Now
                        },
                        new Act(){
                            ActType = ActType.StartTimer,
                            Time = DateTime.Now.AddMinutes(0.5)
                        },
                        new Act(){
                            ActType = ActType.AddPomo,
                            Time = DateTime.Now.AddMinutes(25.5)
                        }
                    }
            };
            return task;
        }

        #endregion
    }
}
